package com.tbit.main.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.tbit.main.constant.*;
import com.tbit.main.dao.core.MachineFaultDao;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.*;
import com.tbit.main.service.*;
import com.tbit.main.util.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 车辆故障
 *
 * @author Leon
 * 2019年11月16日 下午2:56:53
 */
@Service("machineFaultService")
public class MachineFaultServiceImpl implements MachineFaultService {
    @Autowired
    private MachineFaultDao machineFaultDao;
    @Autowired
    private DataService dataService;
    @Resource
    private MachineService machineService;
    @Resource
    private MachineFaultLogService machineFaultLogService;
    @Resource
    private GeoreMachineService georeMachineService;
    @Resource
    private WorkOrderConfigService workOrderConfigService;
    @Resource
    private WorkOrderFinishingService workOrderFinishingService;
    @Resource
    private WorkOrderService workOrderService;
    @Resource
    private WorkOrderQuartzService workOrderQuartzService;


    @Override
    public MachineFault getByMachineId(Integer machineId) {
        return machineFaultDao.getByMachineId(machineId);
    }

    @Override
    public List<MachineFault> getByMachineIds(List<Integer> machineIds) {
        return CollUtil.isEmpty(machineIds)
                ? Collections.emptyList()
                : machineFaultDao.selectByMachineIds(StringUtil.getListString(machineIds));
    }

    @Override
    public void insert(MachineFault machineFault) {
        machineFault.setUpdateTime(DateTimeUtil.getNowTime());
        machineFaultDao.insert(machineFault);
    }

    @Override
    public void update(MachineFault machineFault) {
        machineFault.setUpdateTime(DateTimeUtil.getNowTime());
        machineFaultDao.update(machineFault);
    }

    @Override
    public void del(Integer machineId) {
        machineFaultDao.del(machineId);
    }

    @Override
    public List<MachineFault> getByAccountId(Integer accountId) {
        return machineFaultDao.getByAccountId(accountId);
    }

    @Override
    public List<MachineFault> getByAccountIds(List<Integer> accountIds) {
        Map<String, Object> params = new HashMap<>();
        params.put(DaoParamConstant.accountIds, StringUtil.getListString(accountIds));
        return machineFaultDao.getByAccountIds(params);
    }

    @Override
    public List<MachineFault> getByRegionId(List<Integer> regionId) {
        return machineFaultDao.getByRegionId(StringUtil.getListString(regionId));
    }

    @Override
    public String getImageByMachineId(Integer machineId) {
        return machineFaultDao.getImageByMahineId(machineId);
    }

    @Override
    public List<Map<String, Object>> getGroupByAccountId() {
        return machineFaultDao.getGroupByAccountId();
    }

    @Override
    public Integer getByAccountIdType(Integer accountId, Integer from) {
        Map<String, Object> map = new HashMap<>();
        map.put(DaoParamConstant.accountId, accountId);
        map.put("from", from);
        return machineFaultDao.getByAccountIdType(map);
    }

    @Override
    public List<Integer> getExist(List<Integer> list, Integer from) {
        Map<String, Object> map = new HashMap<>();
        map.put("list", list);
        map.put("from", from);
        return machineFaultDao.getExist(map);
    }

    @Override
    public List<MachineFault> getMachineFaultUser(Integer accountId, Integer machineId, List<Integer> machineIds) {

        AccountConfigExt accountConfigExtDay = dataService.getAccountidExt(accountId + AccountConfigExtConstant.USER_SIGN_FAULT_DAY);
        AccountConfigExt accountConfigExtCount = dataService.getAccountidExt(accountId + AccountConfigExtConstant.USER_SIGN_FAULT_COUNT);

        if (accountConfigExtDay != null || accountConfigExtCount != null) {
            Map<String, Object> map = new HashMap<>();
            map.put("accountId", accountId);
            map.put("day", Integer.valueOf(accountConfigExtDay.getParamValue()));
            map.put("count", Integer.valueOf(accountConfigExtCount.getParamValue()));
            map.put("machineId", machineId);
            map.put("machineIds", StringUtil.getListString(machineIds));
            return machineFaultDao.getMachineFaultUser(map);
        } else {
            return null;
        }

    }

    @Override
    public void batchClearMachineFaultById(List<Integer> machineIdList) {
        machineFaultDao.batchClearMachineFaultById(machineIdList);
    }

    public void addMachineFault(MachineFault machineFault, AccountUser accountUserToken){
        //查询设备信息
        Machine machine = machineService.getByUseCode(machineFault.getUserCode());
        if (Objects.isNull(machine)) {
            throw new BaseException("Machine.notExist");
        }
        //设备权限判断
        machineService.auth(accountUserToken.getAgents(), machine.getMachineId());
        machineFault.setMachineId(machine.getMachineId());

        MachineFaultLog machineFaultLog = new MachineFaultLog();
        machineFaultLog.setFaults(machineFault.getFaults());
        MachineFault machineFaultDB = getByMachineId(machine.getMachineId());
        //检查故障是否是疑似故障
        machineFaultDB = this.checkMachineSuspectedFault(machineFaultDB);
        if (machineFaultDB == null) {
            Assert.hasLength(machineFault.getFaults(), "Machine.fault.type.notNull");
            Assert.hasLength(machineFault.getRemark(), "Machine.fault.remark.notNull");
            if (machineFault.getImageIds() == null) {
                machineFault.setImageIds("");
            }
            String userReportedOrderNo = machineFaultLogService.selectUserReportedFaultsOrderNoByMachineId(machine.getMachineId());
            String orderNo = StringUtils.defaultIfBlank(userReportedOrderNo, OrderUtil.getNO());
            //申报人
            machineFault.setAddMan(accountUserToken.getName());
            machineFault.setOrderNO(orderNo);
            insert(machineFault);
            machineFaultLog.setOrderNO(orderNo);
            machineFaultLog.setFaultType(MachineFaultLogConstant.REPAIR_REQUEST);
        } else {

            if (machineFaultDB.getFrom() == 1) {
                machineFaultLog.setFaultType(MachineFaultLogConstant.REVIEW_AND_REPORT);
            } else {
                machineFaultLog.setFaultType(MachineFaultLogConstant.FAULT_UPDATE);
            }
            if (machineFaultDB.getOrderNO() == null) {
                machineFault.setOrderNO(OrderUtil.getNO());
                machineFaultLog.setOrderNO(machineFault.getOrderNO());
            } else {
                machineFaultLog.setOrderNO(machineFaultDB.getOrderNO());
            }

            /*替换可修改字段 覆盖用户上报的故障信息 申报人*/
            machineFault.setAddMan(accountUserToken.getName());
            machineFault.setFrom(0);
            ObjectUtil.assign(machineFault, machineFaultDB, null);
            update(machineFaultDB);
        }

        /*添加故障上报日志*/
        machineFaultLog.setAccountId(machine.getAccountId());
        GeoreMachine georeMachine = georeMachineService.getByMachineId(machine.getMachineId());
        if (georeMachine != null) {
            machineFaultLog.setRegionId(georeMachine.getRegionId());
        }
        machineFaultLog.setMachineId(machine.getMachineId());
        machineFaultLog.setUserCode(machine.getUserCode());
        machineFaultLog.setAddManId(accountUserToken.getAccountUserId());
        machineFaultLog.setAddTime(DateTimeUtil.getNowTime());
        machineFaultLog.setImageIds(machineFault.getImageIds());
        machineFaultLog.setIntoMain(0);
        machineFaultLog.setPoint(machineFault.getPoint());
        machineFaultLog.setMachineType(machine.getMachineType());
        machineFaultLog.setRemark(machineFault.getRemark());
        machineFaultLog.setAddManName(accountUserToken.getName());
        machineFaultLog.setAddManPhone(accountUserToken.getPhone());
        machineFaultLogService.insert(machineFaultLog);


        /*生成工单*/
        WorkOrderConfig workOrderConfig = workOrderConfigService.getByAccountId(machine.getAccountId());
        if (workOrderConfig != null && workOrderConfig.getRepairSwitch()) {

            WorkOrderFinishing workOrderFinishing = workOrderFinishingService.getByWorkMachineIdState(WorkOrderConstant.workType_WX, machine.getMachineId(), null);
            if (workOrderFinishing != null) {
                LogUtil.info("已存在删除维修工单:" + workOrderFinishing.getWorkOrderId());
                workOrderService.del(workOrderFinishing.getWorkOrderId());
                workOrderFinishingService.del(workOrderFinishing.getWorkOrderId());
            }
            workOrderQuartzService.workOrder(null, workOrderConfig, machine,
                    dataService.getByGeoMachineId(machine.getMachineId()), WorkOrderConstant.workType_WX, WorkOrderConstant.state_CJ, null);
        }
        /**更改车辆状态*/
        machineService.changeState(machine.getMachineId(), MachineStateConstant.MACHINE_STATE_GZ);
    }


    /**
     * 检查故障是否是疑似故障，如果是疑似故障则删除掉疑似故障，把正式的故障加入
     * @param machineFaultInDbd machineFault
     * @return MachineFault
     */
    private MachineFault checkMachineSuspectedFault(MachineFault machineFaultInDbd){
        //故障为空，或者不是疑似故障，则直接返回
        if (Objects.isNull(machineFaultInDbd) || !Objects.equals(machineFaultInDbd.getFrom(),4)){
            return machineFaultInDbd;
        }
        del(machineFaultInDbd.getMachineId());
        return null;
    }
}
